package nus.mtech.call;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;

public class CallManager {

	private static HashMap<String, ArrayList<Call>> mapCallUsage = null;
	private static CallManager CallManagerInstance = null;

	public static CallManager getCallManagerInstance() {
		if (CallManagerInstance != null)
			return CallManagerInstance;
		else
			return CallManagerInstance = new CallManager();
	}
	
	public CallManager(){
		mapCallUsage = new HashMap<String, ArrayList<Call>>();
	}

	// Get total call usage by call type for the month we want to bill
	// CallTypes : 1 - IDD, 2 - ROAMING, 3 - LOCAL CALL
	public int calculateUsageByCallType(String accountNo, Date billDate,
			int callType) {
		ArrayList<Call> lstCalls = this.getCallsByAccountNo(accountNo);
		int totalDuration = 0;
		if(null != lstCalls){
			for (Call call : lstCalls) {
				if (call.getCallType() == callType
						&& isSameMonth(billDate, call.getCallDate())) {
					totalDuration += call.getCallDurationSecond();
				}
			}
		}
		return totalDuration;
	}

	// Get all the calls under an account
	public ArrayList<Call> getCallsByAccountNo(String accountNo) {
		return mapCallUsage.get(accountNo);
	}

	private boolean isSameMonth(Date billDate, Date callDate) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(billDate);

		Calendar startDate = (Calendar) cal.clone();
		Calendar endDate = (Calendar) cal.clone();

		startDate.set(Calendar.DATE, 1);

		endDate.add(Calendar.MONTH, 1);
		endDate.set(Calendar.DATE, 1);
		endDate.add(Calendar.DATE, -1);

		return startDate.getTime().compareTo(callDate)
				* callDate.compareTo(endDate.getTime()) > 0;
	}

	// To populate raw data from the call file
	public void populateCallMap(ArrayList<Call> lstCalls) {
		for (Call call : lstCalls) {
			addCallDatatoMap(call.getAccountNo(), call);
		}
	}

	private void addCallDatatoMap(String accountNo, Call callObj) {
		if (mapCallUsage.containsKey(accountNo)) {
			mapCallUsage.get(accountNo).add(callObj);
		} else {
			ArrayList<Call> alistCall = new ArrayList<Call>();
			alistCall.add(callObj);

			mapCallUsage.put(accountNo, alistCall);
		}
	}


}
